﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;

namespace TfsWrapper
{
    class Remoting
    {
        private static string ServiceName
        {
            get { return "TfsIssueTracker"; }
        }

        private static string ChannelName
        {
            get { return "TeamCity-TFS-" + typeof(Remoting).Assembly.GetName().Name; }
        }

        public static class Client
        {
            public static void Execute(IEnumerable<string> args)
            {
                IChannel channel = new IpcClientChannel();
                ChannelServices.RegisterChannel(channel, false);
                
                try
                {
                    var result = Proxy.Execute(args);

                    Console.Out.Write(result.Out);
                    Console.Error.Write(result.Error);
                }
                finally
                {
                    ChannelServices.UnregisterChannel(channel);
                }
            }

            private static ITfsRemotingWrapper Proxy
            {
                get
                {
                    return (ITfsRemotingWrapper)Activator.GetObject(typeof (ITfsRemotingWrapper), String.Format("ipc://{0}/{1}", ChannelName, ServiceName));
                }
            }

            public static void StartServerProcess()
            {
                var startInfo = new ProcessStartInfo(new Uri(typeof (Remoting).Assembly.CodeBase).LocalPath,
                                                     "-mode=server")
                                {
                                    ErrorDialog = false,
                                    UseShellExecute = true,
                                    WindowStyle = ProcessWindowStyle.Hidden
                                };
                //LogManager.GetLogger(typeof(Program)).Info("Start server: " + startInfo.FileName);
                Process.Start(startInfo);
            }
        }

        public static class Server
        {
            public static event Action OnExit = () => {};

            static Server()
            {
                RemotingConfiguration.RegisterWellKnownServiceType(typeof(TfsRemotingWrapperDecorator), ServiceName, WellKnownObjectMode.Singleton);
            }

            public static IDisposable Auditing
            {
                get { return Shutdown.Auditing(); }
            }

            public static void Run()
            {
                IChannel channel = new IpcServerChannel(ChannelName);
                ChannelServices.RegisterChannel(channel, false);
                ShutdownHandle.Wait();
                ChannelServices.UnregisterChannel(channel);
            }

            public static void Exit()
            {
                OnExit();
                ShutdownHandle.LetGo();
            }
        }
    }
}